package com.dxt;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * Optional类
 */
public class OptionalDemo {

    public static void main(String[] args) {

//        test01();

//        test02();

        test03();
    }


    /**
     * 1. 过滤
     *   filter() : 有数据的optional经过过滤后，如果所有元素都不满足条件，会变成一个无数据的optional
     * 2. 判断 optional对象中是否存在数据
     *   isPresent()
     * 3. 数据转换
     *   map() : 转换后的数据依旧被optional对象封装
     */
    public static void test03(){
        Optional<Author> authorOptional = getAuthorOptional();

        //1. filter
        authorOptional.filter(author -> author.getAge() > 100)
                .ifPresent(author -> System.out.println(author.getName()));
        authorOptional.filter(author -> author.getAge() > 10)
                .ifPresent(author -> System.out.println(author.getName()));

        //2. isPresent()
        boolean present = authorOptional.filter(author -> author.getAge() > 100)
                .isPresent();
        System.out.println(present);

        //3. map()
        Optional<List<Book>> bookOptional = authorOptional.map(author -> author.getBooks());
        bookOptional.ifPresent(books -> System.out.println(books));

    }

    /**
     * 1. 安全消费数据
     *  ifPresent()
     * 2. 获取值
     *  get() : 不安全
     * 3. 安全获取值
     *  orElseGet(): 当获取的数据为空时，返回我们设置的默认值
     *  orElseThrow(): 当获取的数据为空时，使用传入的参数创建异常抛出
     */
    public static void test02(){
        Optional<Author> authorOptional = getAuthorOptional();

        //1. ifPresent()
        authorOptional.ifPresent(author -> System.out.println(author));

        //2. get()
        Author author = authorOptional.get();
        System.out.println(author.getName());
        Optional<Object> empty = Optional.empty();  //使用get()获取空值，会报异常
//        System.out.println("empty: " + empty.get());

        //3. orElseGet()
        Author author1 = authorOptional.orElseGet(()->new Author());
        System.out.println(author1);
        System.out.println("empty1: " + empty.orElseGet(() -> new Author()));

        //4. orElseThrow()
        try {
            Author author2 = authorOptional.orElseThrow(() -> new RuntimeException("数据为null"));
            System.out.println(author2);
            System.out.println("empty2: " + empty.orElseThrow(() -> new RuntimeException("数据为null")));
        } catch (Throwable throwable) {
            System.out.println(throwable.getMessage());
//            throwable.printStackTrace();
        }

    }

    /**
     * 创建Optional对象
     * 1. ofNullable(): 传入的数据可以为空
     * 2. of(): 传入的数据不为空
     * 3. empty(): 如果需要将空数据封装成Optional对象，则使用empty()
     */
    public static void test01(){
        Author author = getAuthor();
        //ofNullable()
        Optional<Author> authorOptional = Optional.ofNullable(author);
        authorOptional.ifPresent(element -> System.out.println(element.getName()));
        //常见的使用方法是返回一个 Optional 对象
        Optional<Author> authorOptional1 = getAuthorOptional();
        authorOptional1.ifPresent(element -> System.out.println(element.getName()));

        //2. of()
        Optional<Author> authorOptional2 = Optional.of(author);
        authorOptional2.ifPresent(element -> System.out.println(element.getName()));

        //3. empty()
        Optional<Object> empty = Optional.empty();
        empty.ifPresent(element -> System.out.println("empty: " + element));


    }

    public static Optional<Author> getAuthorOptional(){
        Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);

        List<Book> books1 = new ArrayList<Book>();
        books1.add(new Book(1L, "Java", "程序设计语言,计算机", 88, "java语言基础"));
        books1.add(new Book(2L, "c++", "底层程序设计语言,计算机", 80, "c++语言基础"));
        author.setBooks(books1);

        return Optional.ofNullable(author);
    }

    public static Author getAuthor(){
        Author author = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);
        return author;
    }
}
